package cn.com.okgo.request.base;

import java.io.IOException;

import cn.com.okgo.callback.HttpCallback;
import cn.com.okgo.utils.ThreadUtils;
import okhttp3.MediaType;
import okhttp3.RequestBody;
import okio.Buffer;
import okio.BufferedSink;
import okio.ForwardingSink;
import okio.Okio;
import okio.Sink;

/**
 * Created by luwenlong on 2017/8/28.
 *
 * 主要用于返回上传进度
 */

public class ProgressRequestBody<T> extends RequestBody {

    private RequestBody requestBody;         //实际的待包装请求体
    private HttpCallback<T> callback;

    public ProgressRequestBody(RequestBody requestBody, HttpCallback<T> callback) {
        this.requestBody = requestBody;
        this.callback = callback;
    }

    @Override
    public MediaType contentType() {
        return requestBody.contentType();
    }

    /**
     * 重写调用实际的响应体的contentLength
     */
    @Override
    public long contentLength() {
        try {
            return requestBody.contentLength();
        } catch (IOException e) {
            return -1;
        }
    }

    @Override
    public void writeTo(BufferedSink sink) throws IOException {
        CountingSink countingSink = new CountingSink(sink);
        BufferedSink bufferedSink = Okio.buffer(countingSink);
        requestBody.writeTo(bufferedSink);
        bufferedSink.flush();
    }

    /**
     * 包装
     */
    private final class CountingSink extends ForwardingSink {

        private long total;
        private long progress;

        public CountingSink(Sink sink) {
            super(sink);
            total = contentLength();
        }

        @Override
        public void write(Buffer source, long byteCount) throws IOException {
            super.write(source, byteCount);
            progress +=byteCount;
            ThreadUtils.dispatchToMainThread(new Runnable() {
                @Override
                public void run() {
                    callback.onUpLoadProgress(progress, total);
                }
            });
        }
    }
}
